package gulimall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sun.xml.internal.ws.util.CompletedFuture;
import gulimall.entity.*;
import gulimall.mapper.SkuInfoMapper;
import gulimall.service.*;
import gulimall.utils.PageUtils;
import gulimall.utils.Query;
import gulimall.vo.SkuItemSalAttrVo;
import gulimall.vo.SkuItemVo;
import gulimall.vo.SpuItemAttrGroupVo;
import gulimall.vo.spusave.Attr;
import gulimall.vo.spusave.SpuSaveVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.swing.*;


@Service("skuInfoService")
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoMapper, SkuInfo> implements SkuInfoService {

    @Resource
    private SkuInfoService skuInfoService;

    @Resource
    private SpuInfoDescService spuInfoDescService;

    @Resource
    private SkuImagesService skuImagesService;

    @Resource
    private ProductAttrValueService productAttrValueService;

    @Resource
    private IAttrGroupService attrGroupService;

    @Resource
    private AttrAttrgroupRelationService attrAttrgroupRelationService;

    @Resource
    private AttrService attrService;

    @Resource
    private SkuSaleAttrValueService skuSaleAttrValueService;

    @Resource
    private ThreadPoolExecutor executor;


    /**
     * sku检索
     *
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String key = (String) params.get("key");//检索条件
        String catelogId = (String) params.get("catelogId");//分类id
        String brandId = (String) params.get("brandId");//品牌id
        String min = (String) params.get("min");//最小价格
        String max = (String) params.get("max");//最大价格

        QueryWrapper<SkuInfo> wrapper = new QueryWrapper<>();

        if (StringUtils.isNotBlank(catelogId) && !"0".equals(catelogId)) {
            wrapper.lambda().eq(SkuInfo::getCatalogId, catelogId);
        }
        if (StringUtils.isNotBlank(brandId) && !"0".equals(brandId)) {
            wrapper.lambda().eq(SkuInfo::getBrandId, brandId);
        }
        if (!"0".equals(max) && StringUtils.isNotBlank(min) && StringUtils.isNotBlank(max)) {
            BigDecimal minPrice = new BigDecimal(min);
            BigDecimal maxPrice = new BigDecimal(max);
            wrapper.lambda().between(SkuInfo::getPrice, minPrice, maxPrice);
        }

        if (StringUtils.isNotBlank(key)) {
            wrapper.lambda().and(queryWrapper -> {
                queryWrapper.eq(SkuInfo::getSkuId, key)
                        .or().like(SkuInfo::getSkuName, key);
            });
        }


        IPage<SkuInfo> page = this.page(
                new Query<SkuInfo>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }


    /**
     * 根据skuId获取SkuItemVo的信息，显示给商品详情页面
     * 使用线程池，异步编排，多任务共同处理(allOf)
     *
     * @param skuId
     * @return
     * @version 1.0 使用MyBatisPlus完成
     */
    @Override
    public SkuItemVo getItemVo(Long skuId) throws ExecutionException, InterruptedException {

        SkuItemVo skuItemVo = new SkuItemVo();

        //1.sku基本信息获取，pms_sku_info
        CompletableFuture<SkuInfo> skuInfoFuture = CompletableFuture.supplyAsync(() -> {
            SkuInfo skuInfo = skuInfoService.getById(skuId);
            //Long spuId = skuInfo.getSpuId();
            skuItemVo.setSkuInfo(skuInfo);
            return skuInfo;
        }, executor);


        //2.sku的图片信息，pms_sku_images
        CompletableFuture<Void> skuImgFuture = CompletableFuture.runAsync(() -> {
            List<SkuImages> skuImagesList = skuImagesService.list(new LambdaQueryWrapper<SkuImages>().eq(SkuImages::getSkuId, skuId));
            skuItemVo.setImages(skuImagesList);
        }, executor);


        //3.获取spu的销售属性组合
        CompletableFuture<Void> spuSaleAttrFuture = skuInfoFuture.thenAcceptAsync(skuInfo -> {
            Long spuId = skuInfo.getSpuId();
            List<SkuInfo> skuInfoList = skuInfoService.list(new LambdaQueryWrapper<SkuInfo>().eq(SkuInfo::getSpuId, spuId));
            List<Long> skuIds = skuInfoList.stream().map(SkuInfo::getSkuId).collect(Collectors.toList());
            //查询这些skuId对应的所有销售属性
            List<SkuItemSalAttrVo> skuSaleAttrValues = skuSaleAttrValueService.listGroupByAttr(skuIds);
            skuItemVo.setSaleAttr(skuSaleAttrValues);
        }, executor);


        //4.获取spu的介绍
        CompletableFuture<Void> spuDescFuture = skuInfoFuture.thenAcceptAsync(skuInfo -> {
            Long spuId = skuInfo.getSpuId();
            SpuInfoDesc spuInfoDesc = spuInfoDescService.getById(spuId);
            skuItemVo.setDesc(spuInfoDesc);
        }, executor);

        //5.获取spu的基本属性(规格参数)
        //5.1根据spuId查询出基本属性
        CompletableFuture<Void> spuProductAttrFuture = skuInfoFuture.thenAcceptAsync(skuInfo -> {
            Long spuId = skuInfo.getSpuId();
            List<ProductAttrValue> productAttrValues = productAttrValueService.list(new LambdaQueryWrapper<ProductAttrValue>().eq(ProductAttrValue::getSpuId, spuId));
            //5.2获取对应的attrId集合
            List<Long> attrIds = productAttrValues.stream().map(ProductAttrValue::getAttrId).collect(Collectors.toList());

            List<SpuItemAttrGroupVo> groupAttrs = attrIds.stream().map(attrId -> {
                SpuItemAttrGroupVo spuItemAttrGroupVo = new SpuItemAttrGroupVo();

                //1.查询attrId对应的属性分组id
                AttrAttrgroupRelation attrgroupRelation = attrAttrgroupRelationService.getOne(new LambdaQueryWrapper<AttrAttrgroupRelation>()
                        .eq(AttrAttrgroupRelation::getAttrId, attrId));
                Long attrGroupId = attrgroupRelation.getAttrGroupId();
                //2.根据分组id获取对应的分组的名称
                AttrGroup attrGroup = attrGroupService.getById(attrGroupId);
                String attrGroupName = attrGroup.getAttrGroupName();
                spuItemAttrGroupVo.setGroupName(attrGroupName);
                //3.获取该属性分组下的所有属性
                List<AttrAttrgroupRelation> relationList = attrAttrgroupRelationService.list(new LambdaQueryWrapper<AttrAttrgroupRelation>()
                        .eq(AttrAttrgroupRelation::getAttrGroupId, attrGroupId));

                List<Attr> attrs = relationList.stream().map(relation -> {
                    Long groupAttrId = relation.getAttrId();
                    //从pms_product_attr_value表中查出attrId,attrName,attrValue
                    ProductAttrValue productAttrValue = productAttrValueService.getOne(new LambdaQueryWrapper<ProductAttrValue>()
                            .eq(ProductAttrValue::getAttrId, groupAttrId));
                    Attr attr = new Attr();
                    BeanUtils.copyProperties(productAttrValue, attr);
                    return attr;

                }).collect(Collectors.toList());

                spuItemAttrGroupVo.setAttrs(attrs);

                return spuItemAttrGroupVo;
            }).collect(Collectors.toList());

            skuItemVo.setGroupAttrs(groupAttrs);
        }, executor);


        CompletableFuture.allOf(skuInfoFuture, skuImgFuture, spuSaleAttrFuture, spuDescFuture, spuProductAttrFuture).get();

        return skuItemVo;
    }


}